/**
 * 
 * @Project le cOeur - Data Virtualization
 * @Date 08.12.2012
 * @Author Aebi Pascal, Kocher Marc
 * @School BFH-TI Biel, Bachelor Thesis
 *
 */

package main.framework.connection;

import java.io.IOException;
import java.net.ServerSocket;
import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;

import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLServerSocket;

import main.framework.security.KeyStoreManager;
import main.framework.setting.Config;

/**
 * The class ServerSocketFactory is used to create different server sockets.
 */
public class ServerSocketFactory {

	private KeyStoreManager keyStoreManager;

	/**
	 * Creates a server socket creator.
	 * 
	 * @param keyStoreManager The key store manager.
	 */
	public ServerSocketFactory(KeyStoreManager keyStoreManager) {
		this.keyStoreManager = keyStoreManager;
	}
	
	/**
	 * Creates and returns a server socket with the given parameters.
	 * Depending on the given protocol a HTTP or a TLS server socket is created.
	 * The port number dose not matter in this case.
	 * 
	 * @param protocol The protocol.
	 * @param port The port number.
	 * @return The corresponding server socket.
	 * @throws NoSuchAlgorithmException If no Provider supports a TrustManagerFactorySpi implementation for the specified protocol.
	 * @throws KeyManagementException If the init operation fails.
	 * @throws IOException For networking errors.
	 */
	public ServerSocket createServerSocket(Protocol protocol, int port) throws NoSuchAlgorithmException, KeyManagementException, IOException  {
		// HTTPS
		if(protocol.equals(Protocol.TLS)){
	        SSLContext sslContext = SSLContext.getInstance("TLS");
	        sslContext.init(this.keyStoreManager.getKeyManagers(), this.keyStoreManager.getTrustManagers(), new SecureRandom());
	        javax.net.ServerSocketFactory serverSocketFactory = sslContext.getServerSocketFactory();
			SSLServerSocket sslServerSocket = (SSLServerSocket) serverSocketFactory.createServerSocket(port);
			if(Integer.parseInt(Config.ENABLE_CLIENT_AUTHENTICATION) == 1){
				sslServerSocket.setNeedClientAuth(true);
			}
			else{
				sslServerSocket.setNeedClientAuth(false);
			}
			return sslServerSocket;
		}
		// HTTP
		else{
			return new ServerSocket(port);
		}
	}

}
